#include "include.h"
#include "magic.h"
#include "api_alg.h"
/*
 * 文件名称: magic.c
 * 功能描述: 本文件为软件魔音处理模块

 ****************************************************************************************
    code :
    buf  : 3132Bytes
    time : 160M 下 120 个点处理 229us
 */
#if MAGIC_EN

#define FRAME_LEN		        120                       //算法处理帧长
#define PROCESS_OUT_SAMPLES     120                       //每次存取帧长
s16 magic_pingpangcache_temp[FRAME_LEN*2] AT(.buf.pitch_shift); //乒乓buf缓存
static pitch_shift2_cb_t pitch_shift2_cb AT(.buf.pitch_shift.cache);
WEAK volatile u8 magic_flag = 0;                           //乒乓buf 切换标志位
uint8_t magic_in_cnt = 0;                                 //写指针
uint8_t magic_out_cnt = 1;                                //读指针 等待 （2.5ms）再去取

static magic_cfg_t magic_cfg AT(.buf.pitch_shift.cache);

AT(.text.pitch_shift_proc.input)WEAK
void magic_audio_input(u8 *ptr, u32 samples, int ch_mode, void *params)
{
    s16 *rptr = (s16 *)ptr;
	//printf("samples:%d->ch_mode:%d\n",samples,ch_mode);
    if(magic_cfg.mute){
        if (magic_cfg.callback) {
            magic_cfg.callback((u8 *)ptr, samples, ch_mode, params);
        }
    }else{
        if (!wireless_role_is_adapter()) {//device
            uint8_t process_num = samples/PROCESS_OUT_SAMPLES;
            s16 *process_pcm_ptr = (s16 *)ptr;
            if (process_num*PROCESS_OUT_SAMPLES != samples) {
                printf("magic input samples err\n");
                return;
            }
            while (process_num) {
                ///IN存 PING-PONG BUFFER
                memcpy(&magic_pingpangcache_temp[magic_in_cnt * PROCESS_OUT_SAMPLES], process_pcm_ptr, PROCESS_OUT_SAMPLES * 2);
                magic_in_cnt++;
                ///kick 低优先级线程处理
                if(magic_in_cnt == FRAME_LEN/PROCESS_OUT_SAMPLES){
                    magic_flag = 1;
                    magic_mic_proc_kick_start();
                }else if(magic_in_cnt >= FRAME_LEN*2/PROCESS_OUT_SAMPLES){
                    magic_in_cnt = 0;
                    magic_flag = 2;
                    magic_mic_proc_kick_start();
                }
                ///OUT取 PING-PONG BUFFER
                memcpy(process_pcm_ptr,&magic_pingpangcache_temp[magic_out_cnt * PROCESS_OUT_SAMPLES],PROCESS_OUT_SAMPLES*2);
                magic_out_cnt++;
                if(magic_out_cnt>=FRAME_LEN*2/PROCESS_OUT_SAMPLES){
                    magic_out_cnt = 0;
                }
                process_num--;
                if (magic_cfg.callback) {
                    magic_cfg.callback((u8 *)rptr, samples, ch_mode, params);
                }
            }
        }else{//adapt
            pitch_shift2_process(rptr, &pitch_shift2_cb);
            if (magic_cfg.callback) {
                magic_cfg.callback((u8 *)rptr, samples, ch_mode, params);
            }
        }
    }

}

//magic算法启动计算 放在低优先级现场处理
AT(.text.pitch_shift_proc)WEAK
void magic_mic_proc_cb(void)
{
    s16 *ptr = &magic_pingpangcache_temp[0];
    if(magic_flag == 2){
        ptr = &magic_pingpangcache_temp[FRAME_LEN];
    }
    pitch_shift2_process(ptr, &pitch_shift2_cb);
    magic_flag = 0;
}

AT(.text.pitch_shift_set.callback)
void magic_audio_output_callback_set(audio_callback_t callback)
{
    magic_cfg.callback = callback;
}

AT(.text.pitch_shift_init)WEAK
void magic_audio_init(u8 sample_rate, u16 samples)
{
    u16 sample_rete_b[5] = {48000,44100,38000,32000,24000};

    memset(&magic_cfg, 0, sizeof(magic_cfg_t));
    magic_cfg.sample_rate = sample_rate;
    magic_cfg.samples = samples;
	printf("sample_rate:%d->samples:%d\n",sample_rate,samples);
    pitch_shift2_init(sample_rete_b[magic_cfg.sample_rate],MAGIC_SHIFT_LEVEL, &pitch_shift2_cb);
}

AT(.text.pitch_shift_set.param)
void magic_audio_param_set(s32 magic_param)
{
    u16 sample_rete_b[5] = {48000,44100,38000,32000,24000};
	printf("sample_rate:%d->magic_param:%d\n",magic_cfg.sample_rate,magic_param);
    pitch_shift2_init(sample_rete_b[magic_cfg.sample_rate],magic_param, &pitch_shift2_cb);
}

AT(.text.pitch_shift_set.mute)
void magic_audio_mute_set(uint8_t mute)
{
    magic_cfg.mute = mute;
}
AT(.text.pitch_shift_get.mute)
u8 magic_audio_mute_get(void)
{
    return magic_cfg.mute;
}

AT(.text.pitch_shift_exit)
void magic_audio_exit(void)
{
}

#endif //MAGIC_EN
